package main

import (
	"bytes"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"golang.org/x/text/encoding/simplifiedchinese"
)

var (
	gbkDecoder = simplifiedchinese.GBK.NewDecoder() // GBK 解码类。
	osLang     = strings.ToLower(os.Getenv("LANG")) // 操作系统的语言设置。
)

// 关闭指定PID的进程，包括子进程。
func killProcess(pid int) error {
	// 使用`taskkill`强制关闭进程树。
	cmd := exec.Command("taskkill", "/t", "/f", "/pid", strconv.FormatInt(int64(pid), 10))
	return cmd.Run()
}

// 标准输出。
type stdOutput struct {
	lines []string     // 输出内容文本。
	buf   bytes.Buffer // 表示未刷新输出缓存时的输出内容。进程刷新输出缓存时，会将当前缓存的内容变为文本并追加到`lines`。
}

// `stdOutput` 的方法。
//

// 刷新缓存内容到`lines`中。然后清空缓存。
func (so *stdOutput) flush() {
	var rawBytes []byte
	var err error
	if strings.HasPrefix(osLang, "zh_cn") {
		if rawBytes, err = gbkDecoder.Bytes(so.buf.Bytes()); err != nil {
			rawBytes = so.buf.Bytes()
		}
	} else {
		rawBytes = so.buf.Bytes()
	}

	lines := strings.Split(string(rawBytes), "\n")
	if len(lines) > 0 {
		so.lines = append(so.lines, lines...)
		if len(so.lines) > 1000 {
			so.lines = so.lines[0:1000]
		}
	}

	so.buf.Reset()
}

// 参见 `io.Writer#Write(data []byte) (n int, err error)`
func (so *stdOutput) Write(data []byte) (n int, err error) {
	for _, c := range data {
		if c == '\n' {
			// 遇到新行符时刷新缓存。
			so.flush()
		} else {
			so.buf.WriteByte(c)
		}
	}

	return len(data), nil
}
